Learning GeoPandas

Here is one way of getting the solution. There are others, feel free to share yours.

import geopandas as gpd
import contextily as ctx

Download data.

price = gpd.read_file("https://martinfleischmann.net/sds/geographic_data/data/SED_CenovaMapa_p_shp.zip")
districts = gpd.read_file("https://martinfleischmann.net/sds/geographic_data/data/MAP_MESTSKECASTI_P_shp.zip")
price["CENA"] = price["CENA"].replace("N", None).astype('float')

Interactive:

m = price.explore("CENA", legend=True, tiles="CartoDB Voyager", cmap="plasma", style_kwds={"fillOpacity": .5})
districts.boundary.explore(m=m, color="red")
Make this Notebook Trusted to load map: File -> Trust Notebook

Static:

ax = price.plot("CENA", legend=True, cmap="plasma", alpha=.5)
districts.boundary.plot(ax=ax, color="red")
ctx.add_basemap(ax=ax, crs=price.crs, source="CartoDB Voyager")

Create a convex hull around each polygon in price.

price["hull"] = price.convex_hull

Calculate the area of these convex hulls.

price["hull_area"] = price["hull"].area

Find the convex hulls with an area between 30th a 70th percentile in the GeoDataFrame. Create a new object (e.g. average) only with them.

min_bound = price["hull_area"].quantile(.3)
max_bound = price["hull_area"].quantile(.7)
average = price.loc[(price["hull_area"] > min_bound) & (price["hull_area"] < max_bound)]

Create a multi-layer map of Prague where the areas within these percentiles are coloured in one colour, and the rest appear in another. Try making it legible enough.

ax = price.plot(color="lightgray")
average.plot(color="red", ax=ax)

Join the two GeoDataFrame using .sjoin() or .overlay() methods.

price_w_district = price.sjoin(districts)

Is the mean price higher in Praha 3 or Praha 6?

sorted_price = price_w_district.groupby("NAZEV_MC")["CENA"].mean().sort_values()
sorted_price
NAZEV_MC
Praha-Přední Kopanina     2634.705882
Praha-Královice           3410.000000
Praha-Lipence             4515.294118
Praha 16                  4622.244898
Praha-Nedvězí             4656.153846
Praha-Běchovice           4801.379310
Praha-Zbraslav            5158.476190
Praha-Dubeč               5211.818182
Praha 19                  5298.923077
Praha-Čakovice            5325.000000
Praha-Zličín              5378.513514
Praha 15                  5390.733333
Praha-Lysolaje            5394.000000
Praha 22                  5426.689655
Praha-Dolní Počernice     5475.227273
Praha-Kolovraty           5540.740741
Praha-Petrovice           5542.500000
Praha-Satalice            5628.333333
Praha-Štěrboholy          5728.333333
Praha-Dolní Měcholupy     5750.465116
Praha-Šeberov             5843.095238
Praha 14                  5866.565657
Praha-Vinoř               5882.244898
Praha-Velká Chuchle       5909.038462
Praha-Kunratice           6019.813084
Praha-Nebušice            6028.928571
Praha-Suchdol             6115.194805
Praha-Lochkov             6125.000000
Praha-Řeporyje            6167.878788
Praha-Slivenec            6341.333333
Praha 20                  6399.017341
Praha 18                  6417.846154
Praha 17                  6425.208333
Praha 12                  6435.731225
Praha-Ďáblice             6474.025974
Praha-Dolní Chabry        6533.389831
Praha 11                  6547.947020
Praha 9                   6825.467836
Praha 10                  6827.514911
Praha 13                  6917.107843
Praha-Libuš               6983.267327
Praha-Koloděje            6984.347826
Praha-Křeslice            7106.470588
Praha-Újezd               7417.948718
Praha-Březiněves          7425.806452
Praha 21                  7440.869565
Praha-Benice              7527.142857
Praha-Klánovice           7967.368421
Praha-Troja               8296.603774
Praha 4                   8572.657807
Praha 8                   8719.891775
Praha 6                   9541.306180
Praha 3                  10522.075472
Praha 5                  10522.378378
Praha 7                  14837.516779
Praha 2                  19011.404959
Praha 1                  40510.645161
Name: CENA, dtype: float64

From the Series above, you can read that Praha 3 is more expensive than Praha 6. Or you can do it programmatically :).

Which district is the cheapest?

Again, you can read that it is Praha-Přední Kopanina. But if you want to get that programmatically, you will need to access the index.

sorted_price.idxmin()
'Praha-Přední Kopanina'

What is the difference between the cheapest and the most expensive one?

sorted_price.max() - sorted_price.min()
37875.93927893738